global with sharing class PlanDistributionBatch implements Database.Batchable<sObject>, Database.Stateful
{
    global String query = '';
    
    global DataAccessControlUtil dacu = null;
    global Map<String, Schema.SObjectField> scSObjectFieldMap = new Map<String, Schema.SObjectField>(); 
    global Set<ID> buSet1;
    global Set<ID> buSet2;
    global Set<ID> buSet3;
    global Set<ID> buSet4;
    global Set<ID> buSet5;
    global PlanDistributionBatch(Set<ID> bu1,Set<ID> bu2,Set<ID> bu3,Set<ID> bu4,Set<ID> bu5)
    {
    	buSet1 = bu1;
		buSet2 = bu2;
		buSet3 = bu3;
		buSet4 = bu4;
		buSet5 = bu5;
		SObject scObj = new Sales_Contract__c();
        dacu = new DataAccessControlUtil();
        if(scSObjectFieldMap.isEmpty())
            scSObjectFieldMap = dacu.getFieldMap(scObj);
    	
    	query = 'select id, callidus_plan__Latest_Attachments__c from callidus_plan__CallidusDataSource__c dsc where dsc.Callidus_Plan__UserId__c in : buSet1 or dsc.Callidus_Plan__UserId__c in : buSet2 or dsc.Callidus_Plan__UserId__c in : buSet3 or dsc.Callidus_Plan__UserId__c in : buSet4 or dsc.Callidus_Plan__UserId__c in : buSet5';
    }
    
    global database.querylocator start(Database.BatchableContext BC)
    {
		Schema.DescribeSobjectResult dsr = CallidusDataSource__c.sObjectType.getDescribe();
		if(dsr.isAccessible())
        {
	        return Database.getQueryLocator(query);
        }
        return null;
    }
    
    global void execute(Database.BatchableContext BC, List<sObject> sObjectList)
    {
		SObject scObj = new Sales_Contract__c();
        if(dacu.isCreateableObjectByUser(scObj).equalsIgnoreCase('success') && dacu.isUpdateableObjectByUser(scObj).equalsIgnoreCase('success'))
        {
	    	String latestAttachments = '';
	    	for(SObject sobj: sObjectList)
	    	{
	    		latestAttachments = (String)sobj.get('callidus_plan__Latest_Attachments__c');
	    	}
	    	if(latestAttachments != null)
	    	{
		    	String[] latestAttachmentsArray = latestAttachments.split(',');
		    	String[] relaceAttachmentValsArray = new String[]{};
		    	for(String s: latestAttachmentsArray)
		    	{
		    		if(s != null && s.length() > 1)
		    		{
			    		String formStringLike = '%'+s+'%';
	                    //Note: Whenever a new Custom field has to be updated, add it to the below Set.
	                    //Reason: The size of the below set will be compared with the size of the filtered set 
	                    Set<String> expectedUpdateableFields = new Set<String>{'AttachmentID__c', 'Plan_Attachments__c'};
	                    
	                    //Get the Fields that can be updated
	                    Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
						if(filteredFields.size() == expectedUpdateableFields.size())
						{							    		
		                    ESAPI.accessController().setSharingMode(SFDCAccessController.SharingMode.WITHOUT);
				    		Sales_Contract__c[] sc = (Sales_Contract__c[])ESAPI.accessController().fetchAsUser('select AttachmentID__c, Plan_Attachments__c from sales_contract__c where plan_attachments__c like \''+formStringLike+'\' order by createddate desc');
				    		if(sc.size() > 1)
				    		{
				    			sc[0].Plan_Attachments__c = sc[0].Plan_Attachments__c.replace(','+s+',',',');
				    			sc[0].Plan_Attachments__c = sc[0].Plan_Attachments__c.replace(s+',','');
				    			sc[0].Plan_Attachments__c = sc[0].Plan_Attachments__c.replace(','+s,'');
				    			sc[0].AttachmentID__c = sc[0].Plan_Attachments__c.split(',')[0];
				    			
		                        SObject sobj = ESAPI.accessController().updateAsUser(sc[0], new List<String>{'Plan_Attachments__c', 'AttachmentID__c'});
							    			
//								update sc;
				    		}
						}
		    		}
		    	}
	    	}
        }
    }//end of execute()
    
    
    global void finish(Database.BatchableContext BC)
    {
    }
    
}